﻿using System;
using DatabaseGroup.SSIS.SourceAdapters.View;
using DatabaseGroup.SSIS.SourceAdapters.Model;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;

namespace DatabaseGroup.SSIS.SourceAdapters.Presenter
{
    /// <summary>
    /// Presenter for handling the Error tab view
    /// </summary>
    public class ErrorTabPresenter
    {
        private readonly IEditorErrorView _view;
        private readonly IComponentModel _model;
        private ErrorTabSettings _settings;

        /// <summary>
        /// Initializes a new instance of the ErrorTabPresenter class
        /// using the view, propertiesModel and outputModel
        /// </summary>
        /// <param name="view">An instance of an IEditorErrorView</param>
        /// <param name="model">An instance of an IComponentModel</param>
        public ErrorTabPresenter(IEditorErrorView view, IComponentModel model)
        {
            _view = view;
            _model = model;

            InitializeView();

            view.ViewSettings += view_ViewSettings;
            view.SavingSettings += view_SavingSettings;
        }

        /// <summary>
        /// Binds the view with the current settings object
        /// </summary>
        /// <param name="sender">The View</param>
        /// <param name="e"></param>
        private void view_ViewSettings(object sender, TabEventArgs e)
        {
            if (e.Tab != EditorViewTab.Error && e.Tab != EditorViewTab.ANY)
                return;

            // TODO: code smell! - sharing settings like this is wrong
            AdvanceTabSettings advanceTabSettings = _view.GetTabSettings<AdvanceTabSettings>(EditorViewTab.Advance);
            _settings.Columns = advanceTabSettings.Columns;
            _view.BindErrorTab(_settings); 
        }

        /// <summary>
        /// Saves the current settings to the component metadata
        /// </summary>
        /// <param name="sender">The View</param>
        /// <param name="e"></param>
        private void view_SavingSettings(object sender, EventArgs e)
        {
            DTSRowDisposition errorDisposition = PresenterUtils.ConvertStringToDisposition(_settings.ComponentErrorHandling);
            DTSRowDisposition truncationDisposition = PresenterUtils.ConvertStringToDisposition(_settings.ComponentTruncationHandling);
            _model.SetStandardOutputDisposition(errorDisposition, truncationDisposition);

            for (int colIndex = 0; colIndex < _settings.Columns.Count; colIndex++)
            {
                errorDisposition = PresenterUtils.ConvertStringToDisposition(_settings.Columns[colIndex].ErrorHandling);
                truncationDisposition = PresenterUtils.ConvertStringToDisposition(_settings.Columns[colIndex].TruncationHandling);
                _model.SetStandardOutputColumnDisposition(colIndex, errorDisposition, truncationDisposition);
            }
        }

        /// <summary>
        /// Creates a new error settings object and loads it with the current
        /// component configuration and binds it to the view
        /// </summary>
        private void InitializeView()
        {
            _settings = new ErrorTabSettings();

            DTSRowDisposition errorDisposition;
            DTSRowDisposition truncationDisposition;

            _model.GetStandardOutputDisposition(out errorDisposition, out truncationDisposition);
            _settings.ComponentErrorHandling = PresenterUtils.ConvertDispositionToString(errorDisposition);
            _settings.ComponentTruncationHandling = PresenterUtils.ConvertDispositionToString(truncationDisposition);
            _settings.ApplyHandling = PresenterUtils.ConvertDispositionToString(DTSRowDisposition.RD_RedirectRow);

            AdvanceTabSettings advanceTabSettings = _view.GetTabSettings<AdvanceTabSettings>(EditorViewTab.Advance);
            _settings.Columns = advanceTabSettings.Columns;

            for (int colIndex = 0; colIndex < _model.StandardOutputColumns; colIndex++)
            {
                _model.GetStandardOutputColumnDisposition(colIndex, out errorDisposition, out truncationDisposition);
                _settings.Columns[colIndex].ErrorHandling = PresenterUtils.ConvertDispositionToString(errorDisposition);
                _settings.Columns[colIndex].TruncationHandling = PresenterUtils.ConvertDispositionToString(truncationDisposition);
            }

            _view.BindErrorTab(_settings);
        }
    }
}
